package com.bcqn.service.impl;

import com.bcqn.dao.MessageMapper;
import com.bcqn.dao.PostCollectionMapper;
import com.bcqn.dao.PostMapper;
import com.bcqn.dao.PostReviewMapper;
import com.bcqn.model.*;
import com.bcqn.service.PostService;
import com.bcqn.vo.PostQueryVo;
import com.bcqn.vo.PostReviewVo;
import com.bcqn.vo.PostVo;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * PostServiceImpl
 *
 * @author Kelly
 * @version v1.0
 * @date 2020/4/17 21:30
 */
@Service
public class PostServiceImpl implements PostService {

    @Autowired
    private PostMapper postMapper;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private PostReviewMapper postReviewMapper;
    @Autowired
    private MessageMapper messageMapper;
    @Autowired
    private PostCollectionMapper postCollectionMapper;
    @Resource
    private RedisTemplate<String,Object> redisTemplate;

    private static Logger logger = LoggerFactory.getLogger(PostReviewServiceImpl.class);



    @Override
    public PageInfo<PostVo> getHotPostList(PostQueryVo postQueryVo) {
        PageHelper.startPage(postQueryVo.getPageNum(), postQueryVo.getPageSize());
        postQueryVo.setLikeWeights(1);
        postQueryVo.setReviewWeights(1.5);
        postQueryVo.setForwardWeights(1.5);
        postQueryVo.setRecommendWeights(10);
        postQueryVo.setHoursWeights(2);
        List<PostVo> postVoList;
        postVoList = postMapper.getHotPostList(postQueryVo);
        for (PostVo postVo:postVoList){
            String userKey = "POST_USERID:"+ postVo.getId()+"-"+postQueryVo.getUserId();
            boolean likeStatus = redisTemplate.hasKey(userKey);
            //从redis中判断用户是否喜欢帖子
            postVo.setLikeStatus(likeStatus);
            List<PostReviewVo> postReviewList  = postReviewMapper.getByPostId(postVo.getId(),1,1,1);
            for (PostReviewVo p:postReviewList ) {
                //装本评论头像和姓名
                User user = postReviewMapper.getUserById(p.getUserId());
                p.setUserAvatar(user.getAvatar());
                p.setUserName(user.getUserName());
                p.setPosition(user.getPosition());
                //装父类评论头像和姓名
                User user1 = postReviewMapper.getUserById(p.getFatherReviewUser());
                if (user1 != null){
                    p.setFatherReviewUserAvatar(user1.getAvatar());
                    p.setFatherReviewUserName(user1.getUserName());
                }
                //查询子评论的总数
                Long sonReviewCount = postReviewMapper.getReviewCount(p.getOriginalReviewId());
                p.setReviewCount(sonReviewCount-1);
                //装用户是否给这个评论点赞
                String reviewKey = "REVIEW_USERID:"+ p.getId()+"-"+postQueryVo.getUserId();
                //从redis中判断用户是否点赞这个评论
                boolean likeReviewStatus = redisTemplate.hasKey(reviewKey);
                p.setLikeStatus(likeReviewStatus);

            }
            postVo.setPostReviewVos(postReviewList);
        }

//        if (postQueryVo.getForumId() == null) {
//            // 查全部分页
//            postVoList = postMapper.getHotPostList(postQueryVo);
//            for (PostVo postVo:postVoList){
//                List<PostReviewVo> postReviewList  = postReviewMapper.getByPostId(postVo.getId(),1,1,1);
//                for (PostReviewVo p:postReviewList ) {
//                    //装本评论头像和姓名
//                    User user = postReviewMapper.getUserById(p.getUserId());
//                    p.setUserAvatar(user.getAvatar());
//                    p.setUserName(user.getUserName());
//                    //装父类评论头像和姓名
//                    User user1 = postReviewMapper.getUserById(p.getFatherReviewUser());
//                    p.setFatherReviewUserAvatar(user1.getAvatar());
//                    p.setFatherReviewUserName(user1.getUserName());
//
//                }
//                postVo.setPostReviewVos(postReviewList);
//            }
//        } else {
//            // 查某个forumId的帖子
//            postVoList = postMapper.getHotPostList(postQueryVo);
//            for (PostVo postVo:postVoList){
//
//
//                List<PostReviewVo> postReviewList  = postReviewMapper.getByPostId(postVo.getId(),1,1,1);
//                for (PostReviewVo p:postReviewList ) {
//                    //装本评论头像和姓名
//                    User user = postReviewMapper.getUserById(p.getUserId());
//                    p.setUserAvatar(user.getAvatar());
//                    p.setUserName(user.getUserName());
//                    //装父类评论头像和姓名
//                    User user1 = postReviewMapper.getUserById(p.getFatherReviewUser());
//                    p.setFatherReviewUserAvatar(user1.getAvatar());
//                    p.setFatherReviewUserName(user1.getUserName());
//
//                }
//                postVo.setPostReviewVos(postReviewList);
//            }
//        }
        PageInfo<PostVo> pageInfo = new PageInfo<>(postVoList);
        return pageInfo;
    }

    @Override
    public PageInfo<PostVo> getLatestPostList(PostQueryVo postQueryVo) {
        PageHelper.startPage(postQueryVo.getPageNum(), postQueryVo.getPageSize());
        List<PostVo> postVoList;

        postVoList = postMapper.getLatestPostList(postQueryVo);
        for (PostVo postVo:postVoList){
            //判断用户是否给喜欢的帖子点赞
            String userKey = "POST_USERID:"+ postVo.getId()+"-"+postQueryVo.getUserId();
            boolean likeStatus = redisTemplate.hasKey(userKey);
            //从redis中判断用户是否喜欢帖子
            postVo.setLikeStatus(likeStatus);
            List<PostReviewVo> postReviewList  = postReviewMapper.getByPostId(postVo.getId(),1,1,1);
            for (PostReviewVo p:postReviewList ) {
                //装本评论头像和姓名
                User user = postReviewMapper.getUserById(p.getUserId());
                p.setUserAvatar(user.getAvatar());
                p.setUserName(user.getUserName());
                p.setPosition(user.getPosition());
                //装父类评论头像和姓名
                User user1 = postReviewMapper.getUserById(p.getFatherReviewUser());
                if (user1 != null){
                    p.setFatherReviewUserAvatar(user1.getAvatar());
                    p.setFatherReviewUserName(user1.getUserName());
                }
                //查询子评论的总数
                Long sonReviewCount = postReviewMapper.getReviewCount(p.getOriginalReviewId());
                p.setReviewCount(sonReviewCount-1);
                //装用户是否给这个评论点赞
                String reviewKey = "REVIEW_USERID:"+ p.getId()+"-"+postQueryVo.getUserId();
                //从redis中判断用户是否点赞这个评论
                boolean likeReviewStatus = redisTemplate.hasKey(reviewKey);
                p.setLikeStatus(likeReviewStatus);
            }
            postVo.setPostReviewVos(postReviewList);
        }

        PageInfo<PostVo> pageInfo = new PageInfo<>(postVoList);
        return pageInfo;
    }

    @Override
    public int update(Post post) {
        int result;
        if (post.getId() == null) {
            post.setUpdateTime(new Date());
            result = postMapper.insertSelective(post);
        } else {
            result = postMapper.updateByPrimaryKeySelective(post);
        }
        return result;
    }

    @Override
    public int updateLike(Long postId, Long userId, Integer likeStatus) {
//        // redis 存储
//        //个人每次点击后总的点赞数的增加+1或者减少-1
//        Long num =  countZan(postId, userId, likeStatus);
//        //生产唯一的id
//        String key = "postId"+postId+"-"+userId;
//        if (likeStatus == 1){
//            redisTemplate.boundValueOps(key).set("zan");
//        }else{
//            redisTemplate.delete(key);
//        }
//
//        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(5);
//        fixedThreadPool.execute(new Runnable() {
//            public void run() {
//                try {
//                    //更新总赞数
//                    insertMessage(postId,userId);
//                    postReviewMapper.updateCountLike(postId,num);
//                } catch (Exception e) {
//                    e.printStackTrace();
//                    logger.error("updateCountLike error");
//                }
//            }
//        });
        // 以reviewId为key查询
        String key = "POSTID:" + postId;
        String userKey = "POST_USERID:"+ postId+"-"+userId;
        if (redisTemplate.hasKey(key)){
            Object o = redisTemplate.opsForValue().get(key);
            if (o != null) {
                try {
                    int likeNum = Integer.parseInt(o.toString());
                    if (likeStatus == 1) {
                        redisTemplate.opsForValue().set(key,likeNum + 1,10L, TimeUnit.MINUTES);
                        // 还需写入数据库post_like，查询也需要判断，看是否使用MQ
                        redisTemplate.opsForValue().set(userKey,1,1L, TimeUnit.DAYS);
                        insertMessage(postId,userId);
                    } else {
                        redisTemplate.opsForValue().set(key,likeNum - 1,10L, TimeUnit.MINUTES);
                        redisTemplate.delete(userKey);
                    }
                } catch (NumberFormatException e) {
                    logger.error("redis value值转换失败");
                    e.printStackTrace();
                }
            }
        } else {
            // 查询数据库
            Post post = postMapper.selectByPrimaryKey(postId);
            int likeCount = post.getLikeCount();
            if (likeStatus == 1) {
                redisTemplate.opsForValue().set(key,likeCount + 1,10L, TimeUnit.MINUTES);
                // 还需写入数据库post_like，查询也需要判断，看是否使用MQ
                redisTemplate.opsForValue().set(userKey,1,1L, TimeUnit.DAYS);
                insertMessage(postId,userId);
            } else {
                if (likeCount == 0) {
                    logger.error("点赞总数为0，无法取消点赞");
                } else {
                    redisTemplate.opsForValue().set(key,likeCount - 1,10L, TimeUnit.MINUTES);
                    redisTemplate.delete(userKey);
                }
            }
        }
        return 1;
    }


//    // 统计某一条帖子 总的赞数
//
//    public long countZan(Long postId, Long userId,Integer likeStatus){
//        long num = 1 ;
//        //帖子的点赞总数的key
//        String key ="postId"+postId;
//        String key1 = "postId"+postId+"-"+userId;
//        //首先判断是点赞还是取消点赞
//        if (likeStatus == 1){
//            //增加赞， 赞的总数加一
//            if (redisTemplate.hasKey(key)){
//                num = Long.valueOf(stringRedisTemplate.boundValueOps(key).get());
//                num = num+1;
//                redisTemplate.boundValueOps(key).set(Long.toString(num));
//            }else {
//                //第一次点赞设置1
//                redisTemplate.boundValueOps(key).set("1");
//            }
//        }else{
//            if (redisTemplate.hasKey(key1)){
//                //取消点赞 ，先判断是否赞过，如果赞过，赞的总数减一
//                num = Long.valueOf(stringRedisTemplate.boundValueOps(key).get());
//                num = num - 1;
//                redisTemplate.boundValueOps(key).set(Long.toString(num));
//            }else{
//                //如果本身没有赞过，赞的总数保持不变
//                if (redisTemplate.hasKey(key)){
//                    num = Long.valueOf(stringRedisTemplate.boundValueOps(key).get());
//                   //num数目不变
//                    redisTemplate.boundValueOps(key).set(Long.toString(num));
//                }
//            }
//        }
//        return num;
//    }


    /*插入信息表*/
    public void insertMessage(Long postId,Long userId){
        Post post = postMapper.getById(postId);
        Message record =new Message();
        record.setTriggerUserId(userId);
        record.setTriggeredUserId(post.getUserId());
        record.setPostId(postId);
        record.setReviewId(null);
        //设置类型- 帖子点赞为1
        record.setType("1");
        record.setContent(post.getContent());
        //设置是否阅读
        record.setHaveRead("0");
        record.setCreateTime(new Date());
        messageMapper.insert(record);

    }

    @Override
    public PostVo getById(Long id,Long userId) {
        PostVo postVo = postMapper.getById(id);
        //添加评论
        String userKey = "POST_USERID:"+ id+"-"+userId;
        boolean likeStatus = redisTemplate.hasKey(userKey);
        //从redis中判断用户是否喜欢帖子
        postVo.setLikeStatus(likeStatus);
        //根据帖子的id查询评论
        List<PostReviewVo> postReviewList = getReviewBypostId(postVo.getId(),1,1,10);
        List<PostReviewVo> postReviewVosList = new ArrayList<>();
            for (PostReviewVo p:postReviewList ) {
                //装本评论头像和姓名
                User user = postReviewMapper.getUserById(p.getUserId());
                p.setUserAvatar(user.getAvatar());
                p.setUserName(user.getUserName());
                p.setPosition(user.getPosition());
                //装父类评论头像和姓名
                User user1 = postReviewMapper.getUserById(p.getFatherReviewUser());
                if (user1 != null){
                    p.setFatherReviewUserAvatar(user1.getAvatar());
                    p.setFatherReviewUserName(user1.getUserName());
                }
                //查询子评论的总数
                Long sonReviewCount = postReviewMapper.getReviewCount(p.getOriginalReviewId());
                p.setReviewCount(sonReviewCount-1);
                //装用户是否给这个评论点赞
                String reviewKey = "REVIEW_USERID:"+ p.getId()+"-"+userId;
                //从redis中判断用户是否点赞这个评论
                boolean likeReviewStatus = redisTemplate.hasKey(reviewKey);
                p.setLikeStatus(likeReviewStatus);
                if (user1 == null){
                    postReviewVosList.add(p);
                }

            }
            postVo.setPostReviewVos(postReviewVosList);
        return postVo;
    }

    //根据帖子的id和类型，来分页查找

    public List<PostReviewVo> getReviewBypostId(Long postId, Integer orderType, Integer PageNum, Integer PageSize) {

        int start = (PageNum - 1)*PageSize;
        List<PostReviewVo> postReviewList =   postReviewMapper.getByPostId(postId,orderType,start,PageSize);
        return postReviewList;
    }




    @Override
    public int collection(Long postId, Long userId,Integer status) {
        PostCollection pc = postCollectionMapper.getByPostIdAndUserId(postId,userId);
        if (pc == null) {
            PostCollection postCollection = new PostCollection();
            postCollection.setPostId(postId);
            postCollection.setUserId(userId);
            postCollection.setStatus(status);
            return postCollectionMapper.insert(postCollection);
        } else {
            return postCollectionMapper.update(pc.getId(),status);
        }
    }

    @Override
    public PageInfo<PostVo> getMyCollection(PostQueryVo postQueryVo) {
        // 联表查询：post_collection + post + user
        PageHelper.startPage(postQueryVo.getPageNum(), postQueryVo.getPageSize());
        List<PostVo> postVoList = postMapper.getMyCollection(postQueryVo);
        return new PageInfo<>(postVoList);
    }

    @Override
    public int batchUpdatePostLike(Map<Long, Integer> map) {
        return postMapper.batchUpdatePostLike(map);
    }
}
